import type { Page } from '@/models';
import type { Result } from '@/utils/request/type';
import type { ActionType, ProTableProps } from '@ant-design/pro-table';
import ProTable from '@ant-design/pro-table';
import type { OptionsType } from '@ant-design/pro-table/es/components/ToolBar';
import type { SortOrder } from 'antd/lib/table/interface';
import { isEqual } from 'lodash-es';
import { FC, useCallback, useEffect, useImperativeHandle, useRef } from 'react';
import styled from 'styled-components';
/**
 * 设定自定义的请求类型
 */
export type Request<T extends Record<string, unknown>> = (
  params: T & {
    pageSize?: number | undefined;
    pageNum?: number | undefined;
  },
  sort: Record<string, SortOrder>,
  filter: Record<string, any>
) => Result<Page<T>>;
/**
 * 自定义的Tableprops
 */
export interface BaseTableProps<
  T extends Record<string, any>,
  U extends Record<string, any> = Record<string, any>,
  ValueType = 'text'
> extends Omit<ProTableProps<T, U, ValueType>, 'request' | 'scroll' | 'options' | 'size'> {
  request?: Request<T>;
  height?: number | string;
  width?: number | string;
  ellipsis?: boolean;
  options?: false | { reload: OptionsType; setting?: boolean };
}

/**
 * 自定义Table，基于ant-desgin/pro-table，封装了部分默认行为，增加了height、width等props
 * @see https://procomponents.ant.design/components/table/
 */
const TableWrap: FC<BaseTableProps<any>> = <
  T extends Record<string, any>,
  U extends Record<string, any> = Record<string, any>,
  ValueType = 'text'
>(
  props: BaseTableProps<T, U, ValueType>
) => {
  const {
    height,
    width = '100%',
    dataSource,
    request,
    pagination,
    params,
    actionRef,
    columns = [],
    options,
    rowClassName,
    cardProps,
    ...restprops
  } = props;
  const paramsRef = useRef(0);
  const lastParam = useRef<U | undefined>(undefined);
  if (!isEqual(lastParam.current, params)) {
    lastParam.current = params;
    paramsRef.current += 1;
  }
  // 创建自定义的request请求
  const tableref = useRef<ActionType>();
  // 自定义ref暴露值
  useImperativeHandle(actionRef, () => tableref.current as ActionType);
  useEffect(() => {
    tableref.current?.setPageInfo!({
      current: 1
    });
  }, [params]);
  const customRequest = useCallback(
    async (params, sort, filter) => {
      let res: { data: T[]; success: true; total: number } = {
        data: [],
        success: true,
        total: 0
      };
      if (request) {
        const { current, ...restParams } = params;
        const resFn = request(
          { pageNum: current, ...restParams },
          sort,
          filter
        ) as unknown as Result<Page<any>>;
        const data = await resFn;
        if (data.ok) {
          res = {
            data: data.data.list || [],
            // success 请返回 true，
            // 不然 table 会停止解析数据，即使有数据
            success: true,
            // 不传会使用 data 的长度，如果是分页一定要传
            total: data.data.rowCount || 0
          };
        }
      } else {
        res.data = (dataSource as T[]) || [];
        res.total = dataSource?.length || 0;
      }
      if (paramsRef.current > 0) {
        paramsRef.current -= 1;
        if (paramsRef.current > 0) {
          tableref.current?.reloadAndRest!();
        }
      }
      return res;
    },
    [request, dataSource]
  );
  let scroll;
  if (height || width) {
    scroll = {} as { x: any; y: any };
    if (height) {
      scroll.y = height;
    }
    if (width) {
      scroll.x = width;
    }
  }

  return (
    <ProTable
      actionRef={tableref}
      bordered
      columns={columns}
      cardProps={{
        ...cardProps,
        bodyStyle: {
          paddingBottom: 20,
          ...(cardProps ? cardProps.bodyStyle : false)
        }
      }}
      params={params}
      options={
        typeof options === 'boolean'
          ? options
          : { fullScreen: false, setting: false, ...options, density: false }
      }
      pagination={
        pagination === false
          ? false
          : {
              simple: false,
              size: 'default',
              pageSize: 10,
              showSizeChanger: true,
              pageSizeOptions: ['10', '20', '50'],
              defaultCurrent: 1,
              current: 1,
              showTotal: (total: number) => `共${total}条`,
              ...pagination
            }
      }
      search={false}
      scroll={scroll}
      rowClassName={(record: any, index: number, indent: any) => {
        const classnames = [index % 2 === 0 ? 'even' : 'odd'];
        if (rowClassName) {
          if (typeof rowClassName === 'string') {
            classnames.push(rowClassName);
          } else {
            classnames.push(rowClassName(record, index, indent));
          }
        }

        return classnames.join(' ');
      }}
      {...restprops}
      request={customRequest}
    />
  );
};
const BaseTable = styled(TableWrap)<{ height?: number | string }>`
  /* height: 100%; */
  .ant-table-container > .ant-table-body {
    height: ${({ height }) => (typeof height === 'number' ? `${height}px` : height)};
  }
  .ant-pro-table-list-toolbar-container {
    padding-top: 0;
  }
  .ant-table-cell {
    width: fit-content;
    overflow: hidden;
    white-space: nowrap;
  }
` as typeof TableWrap;
BaseTable.displayName = 'BaseTable';
export default BaseTable;
